package xcmg.device.web.warehouse;


import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.entity.initialInventory.InitialInventoryDO;
import xcmg.device.dao.entity.initialInventory.InitialInventoryDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseInboundDO;
import xcmg.device.infra.AuthCode;
import xcmg.device.infra.BasicController;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.crm.util.ActionResultUtil;
import xcmg.device.service.vo.barcode.BarcodeManageVO;
import xcmg.device.service.vo.delivery.ManualFinishVO;
import xcmg.device.service.vo.initialInventory.InitialInventoryDetailVO;
import xcmg.device.service.vo.initialInventory.InitialInventoryInboundCreateVO;
import xcmg.device.service.vo.initialInventory.InitialInventoryVO;
import xcmg.device.service.vo.initialInventory.MaterialsListVO;
import xcmg.device.service.warehouse.InitialInventoryService;
import xcmg.device.service.warehouse.WarehouseInboundService;
import xcmg.device.service.warehouse.WarehouseService;
import xcmg.device.util.JedisUtils;
import xcmg.device.util.RedisConstant;
import yb.ecp.fast.infra.annotation.FastMappingInfo;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.Ref;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 期初入库
 * @author
 * @create 2018-03-20 19:12
 **/
@Slf4j
@RestController
@RequestMapping("/initialInventory")
public class InitialInventoryController extends BasicController
{
    @Autowired
    private InitialInventoryService initialInventoryService;
    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private WarehouseService warehouseService;
    @Autowired
    private WarehouseInboundService warehouseInboundService;
    @Autowired
    private JedisUtils jedisUtils;


    @ResponseBody
    @RequestMapping(value = "/import", method = RequestMethod.POST)
    @ApiOperation("零件批量导入")
    @FastMappingInfo(needLogin = true,code = AuthCode.StockIn.BEGINNING_IN_IMPORT)
    public ActionResult importExcel(HttpServletRequest request) throws Exception
    {
        String location = request.getParameter("x-location");
        String remark = request.getParameter("x-remark");
        String area = request.getParameter("x-area");
        String sapCode = request.getParameter("x-sapCode");
        String country = request.getParameter("x-country");

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile(multipartRequest.getFileNames().next());
        String fileName = file.getOriginalFilename();
        Ref<ErrorCode> codeRef = new Ref<>(ErrorCode.Success);

        if (null == fileName || !fileName.trim().endsWith(".xls"))
        {
            return actionResult(ErrorCode.ImportExcelEndWithXLS);
        }

        InputStream in = file.getInputStream();
        List<InitialInventoryDetailVO> detailVOs = initialInventoryService.importExcel(in, getOrgId(), codeRef);


        if (ErrorCode.Success != codeRef.get())
        {
            return actionResult(codeRef.get(), detailVOs);
        }

        if(ListUtil.isNullOrEmpty(detailVOs))
        {
            return actionResult(ErrorCode.InsertNullData);
        }

        ErrorCode errorCode = initialInventoryService.add(detailVOs,location,getOrgId(),getUserId(),getDeptName(),remark,getUserName(),area,sapCode,country);
        if(ErrorCode.Success!=errorCode)
        {
            return actionResult(errorCode);
        }

        return actionResult(ErrorCode.Success);
    }

    @ResponseBody
    @RequestMapping(value = "/checkImport", method = RequestMethod.POST)
    @ApiOperation("零件导入校验")
    @FastMappingInfo(needLogin = true)
    public ActionResult checkImport(HttpServletRequest request) throws Exception
    {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile(multipartRequest.getFileNames().next());
        String fileName = file.getOriginalFilename();
        Ref<ErrorCode> codeRef = new Ref<>(ErrorCode.Success);
        if (null == fileName || !fileName.trim().endsWith(".xls"))
        {
            return actionResult(ErrorCode.ImportExcelEndWithXLS);
        }
            InputStream in = file.getInputStream();
            List<InitialInventoryDetailVO> detailVOs = initialInventoryService.importExcel(in, getOrgId(),codeRef);

        return actionResult(codeRef.get(), detailVOs);
    }


    @RequestMapping(value = "/list", method = RequestMethod.POST)
    @ApiOperation(value = "查询期初入库零件集合")
    @FastMappingInfo(needLogin = true)
    public ActionResult listMaterials(@RequestBody SearchCommonVO<MaterialsListVO> condition) throws Exception
    {
        if (null == condition)
        {
            return actionResult(ErrorCode.IllegalArument);
        }

        if (null == condition.getFilters())
        {
            MaterialsListVO filters = new MaterialsListVO();
            filters.setOrgId(getOrgId());
            condition.setFilters(filters);
        }
        else
        {
            condition.getFilters().setOrgId(getOrgId());
        }

        PageCommonVO pageCommonVO = initialInventoryService.listMaterials(condition);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    @RequestMapping(value = "/listBill", method = RequestMethod.POST)
    @ApiOperation(value = "查询期初入库单列表")
    @FastMappingInfo(needLogin = true)
    public ActionResult listBill(@RequestBody SearchCommonVO<InitialInventoryVO> condition) throws Exception
    {
        if (null == condition)
        {
            return actionResult(ErrorCode.IllegalArument);
        }

        if (null == condition.getFilters())
        {
            InitialInventoryVO filters = new InitialInventoryVO();
            filters.setOrgId(getOrgId());
            condition.setFilters(filters);
        }
        else
        {
            condition.getFilters().setOrgId(getOrgId());
        }

        PageCommonVO pageCommonVO = initialInventoryService.listBill(condition);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    @RequestMapping(value = "/listMaterials", method = RequestMethod.POST)
    @ApiOperation(value = "查询期初入库零件集合")
    @FastMappingInfo(needLogin = true)
    public ActionResult listMaterialsByBill(@RequestBody SearchCommonVO<MaterialsListVO> condition) throws Exception
    {
        if (null == condition)
        {
            return actionResult(ErrorCode.IllegalArument);
        }

        if (null == condition.getFilters())
        {
            MaterialsListVO filters = new MaterialsListVO();
            filters.setOrgId(getOrgId());
            condition.setFilters(filters);
        }
        else
        {
            condition.getFilters().setOrgId(getOrgId());
        }

        PageCommonVO pageCommonVO = initialInventoryService.listMaterials(condition);
        return actionValueResult(pageCommonVO.getPageInfo());
    }
    @RequestMapping(value = "/listForPrint", method = RequestMethod.POST)
    @ApiOperation(value = "查询期初入库零件集合")
    @FastMappingInfo(needLogin = true)
    public ActionResult listMaterialsForPrint(@RequestBody SearchCommonVO<MaterialsListVO> condition) throws Exception
    {
        if (null == condition)
        {
            return actionResult(ErrorCode.IllegalArument);
        }

        if (null == condition.getFilters())
        {
            MaterialsListVO filters = new MaterialsListVO();
            filters.setOrgId(getOrgId());
            condition.setFilters(filters);
        }
        else
        {
            condition.getFilters().setOrgId(getOrgId());
        }
        condition.getFilters().setPrintFlag("1");

        PageCommonVO pageCommonVO = initialInventoryService.listMaterials(condition);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    @RequestMapping(value = "/batchPrint", method = RequestMethod.POST)
    @ApiOperation(value = "批量打印")
    @FastMappingInfo(needLogin = true)
    public ActionResult batchPrint(@RequestBody List<String> ids) throws Exception
    {
        if (ListUtil.isNullOrEmpty(ids))
        {
            return actionResult(ErrorCode.IllegalArument);
        }
        Ref<List<BarcodeManageVO>> printRef = new Ref<>(new ArrayList<>());

        ErrorCode errorCode = initialInventoryService.batchPrint(ids, getOrgId(), getUserId(), getUserName(),printRef);
        if(ErrorCode.Success!=errorCode)
        {
            return actionResult(errorCode);
        }
        return actionValueResult(printRef.get());
    }

    @RequestMapping(value = "/item", method = RequestMethod.GET)
    @ApiOperation("查询期初入库单详情")
    @FastMappingInfo(needLogin = true)
    public ActionResult item(@RequestParam String id)
    {
        return actionValueResult(initialInventoryService.item(id));
    }

    @RequestMapping(value = "/download",method = RequestMethod.POST)
    @ApiOperation("下载零件批量导入模板")
    @FastMappingInfo(needLogin = true)
    public void download() throws Exception {
        initialInventoryService.download();
    }

    @RequestMapping(value = "/downPrintDrives",method = RequestMethod.POST)
    @ApiOperation("下载打印驱动")
    @FastMappingInfo(needLogin = true)
    public void downPrintDrives() throws Exception
    {
        initialInventoryService.downPrintDrives();
    }


    @RequestMapping(value = "/manualFinish", method = RequestMethod.POST)
    @ApiOperation("手动完成单据")
    public ActionResult manualFinish(@RequestBody ManualFinishVO manualFinishVO) throws Exception
    {
        return actionResult(initialInventoryService.manualFinish(manualFinishVO.getBillNo(), manualFinishVO.getMaterialsNo(), getOrgId()));
    }

    /**
     * @Des 期初入库单自动入库
     * @Date 2021/2/5 13:36
     * @Author wangzhaoyu
     * @Param []
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @RequestMapping(value = "inbound" , method = RequestMethod.POST)
    @ApiOperation("期初入库自动入库操作接口")
    @FastMappingInfo(needLogin = true)
    public ActionResult inbound(@RequestBody InitialInventoryInboundCreateVO createVO){
        String initianInventoryId = createVO.getId();
        InitialInventoryDO initialInventory = initialInventoryService.getInitialInventoryById(initianInventoryId);
        if(initialInventory == null){
            return ActionResultUtil.errorActionResult(ErrorCode.InitialInventoryNotExist);
        }
        String billNo = initialInventory.getBillNo();
        //判断期初入库单状态，如果是只有未入库的单据才能进行自动入库操作
        Integer state = initialInventory.getState();
        if(state == null && state.compareTo(0) != 0 && state.compareTo(1) != 0){
            return ActionResultUtil.errorActionResult(ErrorCode.InitialInventoryInboundStatusError);
        }
        //查询未入库或者部分入库的单据零件
        List<InitialInventoryDetailDO> initialInventoryDetails = initialInventoryService.selectNeedInboundsByMainId(initianInventoryId);
        if(CollectionUtils.isEmpty(initialInventoryDetails)){
            return ActionResultUtil.errorActionResult(ErrorCode.NeedInboundInitialInventoryDetailNotExisted);
        }
        String orgId = initialInventory.getOrgId();
        String warehouseCode = initialInventory.getInLocation();
        CompanyInfoDO companyInfoDO = companyInfoService.getByOrgId(orgId);
        Integer isBarcode = companyInfoDO.getIsBarcode();
        int countIsBarCode = warehouseService.countIsBarCode(orgId, warehouseCode);
        if ((null == isBarcode || 0 == isBarcode) && countIsBarCode <= 0){//非条码化企业且仓库不允许条码化返回错误信息
            return ActionResultUtil.errorActionResult(ErrorCode.NonBarcodedWarehousesNotAllowBarCodeEntry);
        }
        //判断扫描储位所属仓库是否和入库单中仓库一致
        WarehouseInboundDO inboundDO = warehouseInboundService.getByOrder(billNo, orgId);
        if (inboundDO == null) {
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),"未找到入库单，请检查业务单号是否正确");
        }
        if (inboundDO.getStatus() != null && inboundDO.getStatus() == 4) {
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),"业务单据已作废！");
        }
        if (inboundDO.getStatus() != null && inboundDO.getStatus() == 2) {
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),"业务单据已完成！");
        }
        if (inboundDO.getStatus() != null && inboundDO.getStatus() == 3) {
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),"业务单据已结单！");
        }
        try{
            String lockKey = RedisConstant.RedisKeyContant.INITIALINVENTORY_AUTOINBOUND_BILLNO_CACHE_KEY+billNo;
            boolean lockExist = jedisUtils.exists(lockKey);
            log.info("根据key：是否存在锁{}",lockExist);
            if(lockExist){
                return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),"历史操作正在处理中，请稍后再试");
            }
            initialInventoryService.initialInventoryAutoInbound(initialInventory,initialInventoryDetails,lockKey);
            return ActionResultUtil.successActionResult();
        }catch (Exception e){
            log.error("期初入库自动入库调用接口异常{}",e);
            return ActionResultUtil.errorActionResult(ErrorCode.Failure);
        }
    }

}
